package de.justphil.tcg.tcgserver.rest.resources;

import static de.justphil.tcg.tcgserver.commons.logging.TCGLogging.restLogger;

import java.util.Collection;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.slf4j.Logger;

import de.justphil.tcg.tcgserver.commons.domain.complete.CCard;
import de.justphil.tcg.tcgserver.commons.domain.complete.CCardInstance;
import de.justphil.tcg.tcgserver.commons.domain.complete.CDeck;
import de.justphil.tcg.tcgserver.commons.domain.complete.CGame;
import de.justphil.tcg.tcgserver.commons.domain.complete.CNewGame;
import de.justphil.tcg.tcgserver.commons.domain.complete.CProperty;
import de.justphil.tcg.tcgserver.commons.domain.complete.CUser;
import de.justphil.tcg.tcgserver.commons.domain.wrappers.ListRes;
import de.justphil.tcg.tcgserver.commons.exceptions.TCGException;
import de.justphil.tcg.tcgserver.commons.i18n.Error;
import de.justphil.tcg.tcgserver.commons.management.Application;
import de.justphil.tcg.tcgserver.commons.management.ClusterBrowser;
import de.justphil.tcg.tcgserver.commons.management.DataManager;
import de.justphil.tcg.tcgserver.rest.resources.base.AbstractResource;
import de.justphil.tcg.tcgserver.rest.resources.helpers.IndexHelper;

@Path("/test")
public class TestResource extends AbstractResource {
	
	private static final Logger log = restLogger(TestResource.class);
	
	private final DataManager dataManager;
	
	public TestResource() {
		dataManager = Application.getDataManager();
	}
	
	
	
	
	
	
	
	@GET
	@Produces(MediaType.TEXT_HTML)
	public Response index( @Context HttpHeaders headers ) {
		
		try {
			log.debug("Client requests TestResource!");
			return ok( IndexHelper.getHtmlFile("test.htm") );
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
    	}
		
	}
	
	@GET
	@Path("/data/users")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllUsers() {
		Collection<CUser> completeUsers = new ClusterBrowser( dataManager ).getAllUsers();
		return ok( new ListRes<CUser>( completeUsers ) );
	}
	
	@GET
	@Path("/data/users/{userId: [0-9]+}/{subRes: [a-zA-Z0-9]+}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getUserSubRes( @PathParam("userId") long userId, @PathParam("subRes") String subRes, @Context HttpHeaders headers ) {
		
		try {
			
			if (subRes.equals( "games" )) {
				Collection<CGame> completeUserGames = new ClusterBrowser( dataManager ).getUserGames(userId);
				return ok( new ListRes<CGame>( completeUserGames ) );
			}
			else if (subRes.equals( "cardInstances" )) {
				Collection<CCardInstance> completeUserCis = new ClusterBrowser( dataManager ).getUserCardInstances(userId);
				return ok( new ListRes<CCardInstance>( completeUserCis ) );
			}
			else if (subRes.equals( "decks" )) {
				Collection<CDeck> completeUserDecks = new ClusterBrowser( dataManager ).getUserDecks(userId);
				return ok( new ListRes<CDeck>( completeUserDecks ) );
			}
			else {
				throw new TCGException(Error.CLIENT_ERROR_INVALID_REQUEST_URI, Response.Status.NOT_FOUND);
			}
			
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
		}
		
	}
	
	@GET
	@Path("/data/games")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllGames() {
		Collection<CGame> completeGames = new ClusterBrowser( dataManager ).getAllGames();
		return ok( new ListRes<CGame>( completeGames ) );
	}
	
	@GET
	@Path("/data/decks")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllDecks( @Context HttpHeaders headers ) {
		
		try {
			Collection<CDeck> completeDecks = new ClusterBrowser( dataManager ).getAllDecks();
			return ok( new ListRes<CDeck>( completeDecks ) );
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
		}
	}
	
	@GET
	@Path("/data/decks/{deckId: [0-9]+}/{subRes: [a-zA-Z0-9]+}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getDeckSubRes( @PathParam("deckId") long deckId, @PathParam("subRes") String subRes, @Context HttpHeaders headers ) {
		
		try {
			
			if (subRes.equals( "cardInstances" )) {
				Collection<CCardInstance> completeDeckCIs = new ClusterBrowser( dataManager ).getDeckCardInstances(deckId);
				return ok( new ListRes<CCardInstance>( completeDeckCIs ) );
			}
			else {
				throw new TCGException(Error.CLIENT_ERROR_INVALID_REQUEST_URI, Response.Status.NOT_FOUND);
			}
			
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
		}
		
	}
	
	@GET
	@Path("/data/cards")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllCards() {
		Collection<CCard> completeCards = new ClusterBrowser( dataManager ).getAllCards();
		return ok( new ListRes<CCard>( completeCards ) );
	}
	
	@GET
	@Path("/data/cards/{cardId: [0-9]+}/{subRes: [a-zA-Z0-9]+}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getCardSubRes( @PathParam("cardId") long cardId, @PathParam("subRes") String subRes, @Context HttpHeaders headers ) {
		
		try {
			
			if (subRes.equals( "cardInstances" )) {
				Collection<CCardInstance> completeCardCIs = new ClusterBrowser( dataManager ).getCardCardInstances(cardId);
				return ok( new ListRes<CCardInstance>( completeCardCIs ) );
			}
			else {
				throw new TCGException(Error.CLIENT_ERROR_INVALID_REQUEST_URI, Response.Status.NOT_FOUND);
			}
			
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
		}
		
	}
	
	@GET
	@Path("/data/cardInstances")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllCardInstances( @Context HttpHeaders headers ) {
		
		try {
			
			Collection<CCardInstance> completeCIs = new ClusterBrowser( dataManager ).getAllCardInstances();
			return ok( new ListRes<CCardInstance>( completeCIs ) );
			
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), headers.getAcceptableLanguages());
		}
		
	}
	
	@GET
	@Path("/data/properties")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllProperties() {
		Collection<CProperty> completeProperties = new ClusterBrowser( dataManager ).getAllProperties();
		return ok( new ListRes<CProperty>( completeProperties ) );
	}
	
	@GET
	@Path("/data/otpGames")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllNewGames() {
		Collection<CNewGame> completeNewGames = new ClusterBrowser( dataManager ).getAllNewGames();
		return ok( new ListRes<CNewGame>( completeNewGames ) );
	}
	
	/* ######################################################################## */
	/* ######################################################################## */
	/* ######################################################################## */
	
	
	/*
	
	@GET
	@Path("/1")
	@Produces(MediaType.APPLICATION_JSON)
	public Response test1( @HeaderParam(RestConfig.REQ_HEADER_ACCEPT_LANGUAGE) String locale ) {
		log.debug("test1()");
		
		try {
			long ciId = 1L;
			
			CardInstance ci = dataManager.getCardInstanceById(ciId);
			log.debug("CI's card name => {}", ci.getCard().getName());
			log.debug("Setting name to {}", "Original Esel");
			ci.getCard().setName("Original Esel");
			//dataManager.updateCardInstance(ciId, ci);
			
			long cardId = ci.getCard().getId();
			
			Card card = dataManager.getCardById(cardId);
			log.debug("Card's name {} in the 'cards' map => {}", cardId, card.getName());
			
			
			
			return ok();
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), locale);
		}
		
	}
	
	@GET
	@Path("/2")
	@Produces(MediaType.APPLICATION_JSON)
	public Response test2( @HeaderParam(RestConfig.REQ_HEADER_ACCEPT_LANGUAGE) String locale ) {
		log.debug("test2()");
		
		try {
			long userId = 5L;
			User u = dataManager.getUserById( userId );
			
			CardInstance randomCI = u.getCardInstances().get(1);
			
			log.debug("Random user card instance {}, {}", randomCI.getId(), randomCI.getCard().getName());
			if (randomCI.getDeckList() != null && randomCI.getDeckList().size() > 0) {
				for (Deck d : randomCI.getDeckList()) {
					log.debug("This instance is part of the '{}' deck!", d.getName());
					log.debug("Complete deck consists of:");
					printDeck(d);
				}
			}
			else {
				log.debug("Null or empty!");
			}
			
			log.debug("###############################");
			
			log.debug("Now setting name to {}", "Original Esel");
			randomCI.getCard().setName("Original Esel");
			
			log.debug("###############################");
			
			log.debug("Random user card instance {}, {}", randomCI.getId(), randomCI.getCard().getName());
			if (randomCI.getDeckList() != null && randomCI.getDeckList().size() > 0) {
				for (Deck d : randomCI.getDeckList()) {
					log.debug("This instance is part of the '{}' deck!", d.getName());
					log.debug("Complete deck consists of:");
					printDeck(d);
				}
			}
			else {
				log.debug("Null or empty!");
			}
			
			return ok();
		}
		catch (TCGException e) {
			return err(e.getMessage(), (Status) e.getExtra(), locale);
		}
		
	}
	
	private void printDeck( Deck d ) {
		for (CardInstance ci : d.getCardInstances()) {
			log.debug("ciId {}, name {} ({})", new Object[] { ci.getId(), ci.getCard().getName(), ci.getCard().getId() });
		}
	}
	
	*/

}
